#!/bin/bash

# SPAM3UK 回滚脚本
# 此脚本用于快速回滚到上一个版本
# 使用方法: ./rollback.sh [backup_path]

set -e

# 配置变量
DEPLOY_DIR="/data/prod/spam3uk"
BACKUP_DIR="/data/prod/backup"
SERVICE_NAME="spam3uk"
PORT="5700"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_debug() {
    echo -e "${BLUE}[DEBUG]${NC} $1"
}

# 检查权限
check_privileges() {
    if [[ $EUID -eq 0 ]]; then
        SUDO=""
    else
        SUDO="sudo"
    fi
}

# 显示可用备份
show_available_backups() {
    echo "📦 可用备份列表:"
    echo "================================"
    
    if [ ! -d "$BACKUP_DIR" ]; then
        log_error "备份目录不存在: $BACKUP_DIR"
        return 1
    fi
    
    local count=0
    for backup in $(ls -1t $BACKUP_DIR/spam3uk-* 2>/dev/null || true); do
        if [ -d "$backup" ]; then
            count=$((count + 1))
            echo "[$count] $(basename $backup)"
            
            if [ -f "$backup/backup-info.txt" ]; then
                echo "    $(grep "备份时间" "$backup/backup-info.txt" 2>/dev/null || echo "    时间: 未知")"
                echo "    $(grep "原版本" "$backup/backup-info.txt" 2>/dev/null || echo "    版本: 未知")"
            fi
            echo
        fi
    done
    
    if [ $count -eq 0 ]; then
        log_error "未找到任何备份"
        return 1
    fi
    
    return 0
}

# 选择备份
select_backup() {
    local backup_path="$1"
    
    # 如果指定了备份路径，直接使用
    if [ ! -z "$backup_path" ]; then
        if [ -d "$backup_path" ]; then
            echo "$backup_path"
            return 0
        else
            log_error "指定的备份路径不存在: $backup_path"
            return 1
        fi
    fi
    
    # 尝试使用最新备份
    local latest_backup=$(cat $BACKUP_DIR/latest-backup.txt 2>/dev/null || echo "")
    if [ ! -z "$latest_backup" ] && [ -d "$latest_backup" ]; then
        echo "$latest_backup"
        return 0
    fi
    
    # 显示可用备份并让用户选择
    if ! show_available_backups; then
        return 1
    fi
    
    echo "请选择要回滚的备份 (输入编号或完整路径):"
    read -p "选择: " choice
    
    if [[ "$choice" =~ ^[0-9]+$ ]]; then
        # 数字选择
        local backups=($(ls -1t $BACKUP_DIR/spam3uk-* 2>/dev/null | head -10))
        local index=$((choice - 1))
        
        if [ $index -ge 0 ] && [ $index -lt ${#backups[@]} ]; then
            echo "${backups[$index]}"
            return 0
        else
            log_error "无效的选择: $choice"
            return 1
        fi
    else
        # 路径选择
        if [ -d "$choice" ]; then
            echo "$choice"
            return 0
        else
            log_error "指定的路径不存在: $choice"
            return 1
        fi
    fi
}

# 验证备份
validate_backup() {
    local backup_path="$1"
    
    log_info "验证备份: $backup_path"
    
    # 检查备份目录存在
    if [ ! -d "$backup_path" ]; then
        log_error "备份目录不存在"
        return 1
    fi
    
    # 检查关键文件
    local required_files=("spam3uk-prod" "spam4uk-config.prod.json")
    for file in "${required_files[@]}"; do
        if [ ! -f "$backup_path/$file" ]; then
            log_warn "警告: 备份中缺少文件 $file"
        fi
    done
    
    log_info "✅ 备份验证通过"
    return 0
}

# 停止当前服务
stop_current_service() {
    log_info "停止当前服务..."
    
    if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
        $SUDO systemctl stop $SERVICE_NAME
        sleep 2
        
        if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
            log_error "服务停止失败"
            return 1
        fi
    fi
    
    # 检查端口占用
    if netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then
        log_warn "端口 $PORT 仍被占用，尝试清理..."
        local processes=$(netstat -tlnp 2>/dev/null | grep ":$PORT " | awk '{print $7}' | cut -d'/' -f1 | sort -u)
        
        for process in $processes; do
            if [ ! -z "$process" ] && [ "$process" != "-" ]; then
                $SUDO kill -TERM $process 2>/dev/null || true
            fi
        done
        
        sleep 2
        if netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then
            log_error "无法释放端口 $PORT"
            return 1
        fi
    fi
    
    log_info "✅ 服务已停止"
    return 0
}

# 备份当前失败的部署
backup_failed_deployment() {
    local failed_backup="$BACKUP_DIR/failed-$(date +%Y%m%d_%H%M%S)"
    
    log_info "备份当前失败的部署到: $failed_backup"
    
    $SUDO mkdir -p $failed_backup
    if [ -d "$DEPLOY_DIR" ] && [ "$(ls -A $DEPLOY_DIR 2>/dev/null)" ]; then
        $SUDO cp -r $DEPLOY_DIR/* $failed_backup/ 2>/dev/null || true
        $SUDO chown -R $(whoami):$(whoami) $failed_backup
        
        # 记录失败信息
        echo "# SPAM3UK 失败部署备份" > $failed_backup/failed-info.txt
        echo "失败时间: $(date)" >> $failed_backup/failed-info.txt
        echo "回滚原因: 手动回滚" >> $failed_backup/failed-info.txt
    fi
    
    log_info "✅ 失败部署已备份"
}

# 执行回滚
perform_rollback() {
    local backup_path="$1"
    
    log_info "开始回滚操作..."
    log_info "源备份: $backup_path"
    log_info "目标部署: $DEPLOY_DIR"
    
    # 清理当前部署目录
    log_info "清理当前部署目录..."
    rm -rf $DEPLOY_DIR/*
    rm -rf $DEPLOY_DIR/.*git* 2>/dev/null || true
    
    # 恢复备份
    log_info "恢复备份文件..."
    cp -r $backup_path/* $DEPLOY_DIR/
    
    # 设置权限
    chmod +x $DEPLOY_DIR/spam3uk-prod 2>/dev/null || true
    chmod +x $DEPLOY_DIR/*.sh 2>/dev/null || true
    chown -R $(whoami):$(whoami) $DEPLOY_DIR
    
    log_info "✅ 文件恢复完成"
}

# 启动服务
start_service() {
    log_info "启动回滚后的服务..."
    
    $SUDO systemctl start $SERVICE_NAME
    sleep 3
    
    if systemctl is-active --quiet $SERVICE_NAME; then
        log_info "✅ 服务启动成功"
        return 0
    else
        log_error "❌ 服务启动失败"
        $SUDO journalctl -u $SERVICE_NAME -n 20
        return 1
    fi
}

# 验证回滚结果
verify_rollback() {
    log_info "验证回滚结果..."
    
    # 检查服务状态
    if ! systemctl is-active --quiet $SERVICE_NAME; then
        log_error "服务未运行"
        return 1
    fi
    
    # 检查端口监听
    if ! netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then
        log_error "端口 $PORT 未监听"
        return 1
    fi
    
    # 健康检查
    sleep 2
    if curl -s -f http://localhost:$PORT/health > /dev/null; then
        log_info "✅ 健康检查通过"
    else
        log_warn "⚠️  健康检查失败，请检查服务配置"
    fi
    
    # API测试
    if curl -s http://localhost:$PORT/api/vehicles | jq . > /dev/null 2>&1; then
        log_info "✅ API接口正常"
    else
        log_warn "⚠️  API接口异常，请检查数据库连接"
    fi
    
    log_info "✅ 回滚验证完成"
    return 0
}

# 显示回滚结果
show_rollback_result() {
    local backup_path="$1"
    
    echo
    echo "🎉 回滚操作完成！"
    echo "================================"
    echo "回滚源: $(basename $backup_path)"
    echo "部署目录: $DEPLOY_DIR"
    echo "服务端口: $PORT"
    echo
    echo "🔗 访问地址:"
    echo "  Web界面: http://118.145.200.164:$PORT"
    echo "  健康检查: http://118.145.200.164:$PORT/health"
    echo
    echo "📋 常用命令:"
    echo "  查看服务状态: sudo systemctl status $SERVICE_NAME"
    echo "  查看日志: sudo journalctl -u $SERVICE_NAME -f"
    echo "  重启服务: sudo systemctl restart $SERVICE_NAME"
    echo
    
    if [ -f "$backup_path/backup-info.txt" ]; then
        echo "📋 回滚版本信息:"
        cat "$backup_path/backup-info.txt"
    fi
}

# 主函数
main() {
    echo "🔄 SPAM3UK 系统回滚工具"
    echo "版本: 1.0"
    echo "时间: $(date)"
    echo "================================"
    
    check_privileges
    
    # 选择备份
    log_info "选择回滚目标..."
    if ! backup_path=$(select_backup "$1"); then
        log_error "无法选择有效的备份"
        exit 1
    fi
    
    # 验证备份
    if ! validate_backup "$backup_path"; then
        log_error "备份验证失败"
        exit 1
    fi
    
    # 显示备份信息
    echo
    log_info "准备回滚到: $(basename $backup_path)"
    if [ -f "$backup_path/backup-info.txt" ]; then
        echo "📋 备份信息:"
        cat "$backup_path/backup-info.txt"
    fi
    echo
    
    # 确认回滚
    read -p "确认要执行回滚操作吗? 这将停止当前服务并恢复到上述版本 (y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        log_info "回滚操作已取消"
        exit 0
    fi
    
    # 执行回滚步骤
    if ! stop_current_service; then
        log_error "停止服务失败"
        exit 1
    fi
    
    backup_failed_deployment
    
    if ! perform_rollback "$backup_path"; then
        log_error "回滚执行失败"
        exit 1
    fi
    
    if ! start_service; then
        log_error "服务启动失败"
        exit 1
    fi
    
    if ! verify_rollback; then
        log_error "回滚验证失败"
        exit 1
    fi
    
    show_rollback_result "$backup_path"
    
    log_info "✅ 回滚操作全部完成！"
}

# 显示帮助信息
show_help() {
    echo "SPAM3UK 回滚脚本使用说明"
    echo "========================"
    echo
    echo "用法:"
    echo "  $0                    # 交互式选择备份进行回滚"
    echo "  $0 /path/to/backup    # 指定备份路径进行回滚"
    echo "  $0 -h|--help          # 显示此帮助信息"
    echo "  $0 -l|--list          # 列出可用备份"
    echo
    echo "示例:"
    echo "  ./rollback.sh"
    echo "  ./rollback.sh /data/prod/backup/spam3uk-v1.0-20250109_143022"
    echo "  ./rollback.sh --list"
    echo
}

# 处理命令行参数
case "${1:-}" in
    -h|--help)
        show_help
        exit 0
        ;;
    -l|--list)
        show_available_backups
        exit 0
        ;;
    *)
        main "$@"
        ;;
esac
